package com.jdn;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: arsentyev
 * Date: 21.08.12
 */
public class Reflect {
    public static void fill(String clazz, Map<String, String> map, Container container) throws ClassNotFoundException {
        Class cl = Class.forName(clazz);
        container.setClassName(cl.getSimpleName());

        if(cl.isInterface() || cl.isAnnotation() && cl.isEnum()) {
            throw new ClassNotFoundException();
        }

        String ss = null;

        Method[] methods = cl.getDeclaredMethods();
        for(Method m: methods) {
            ss = checkString(m.toString(), clazz);
            container.addMethod(new Container.Wrapper(getName(m.toString()), map.get(ss), "public"));
        }
        Constructor[] cons = cl.getDeclaredConstructors();
        for(Constructor c: cons) {
            ss = checkString(c.toString(), clazz);
            container.addConstructor(new Container.Wrapper(getName(c.toString()), map.get(ss), "public"));
        }
        Field[] fs = cl.getDeclaredFields();
        for(Field f: fs) {
            ss = checkString(f.toString(), clazz);
            container.addField(new Container.FieldWrapper(f.getName(), map.get(ss), "private", getType(f.toString(), f.getDeclaringClass().getName() + "." + f.getName())));
        }

        container.setPackageName(cl.getPackage().getName());

        Container.Hierarchy ch = new Container.Hierarchy(cl.getName(), null);
        if(cl.isInterface()) {
            Class[] sups = cl.getInterfaces();
            if (sups != null && sups.length > 0) {
//                ch = new Container.Hierarchy(sup.getName(), ch);
//                sup = sup.getSuperclass();
            }
        } else {
            Class sup = cl.getSuperclass();
            while (sup != null) {
                ch = new Container.Hierarchy(sup.getName(), ch);
                sup = sup.getSuperclass();
            }
        }
        container.setHierarchy(ch);
    }

    private static String getNames(Class[] classes) {
        String s = "";
        for(Class cl: classes) {
            ;
        }
        return s;
    }

    private static String checkString(String s, String name) {
        return s.replace(name + ".", "").replaceAll("[a-z]+\\.", "").trim().replaceAll("\\s+", " ");
    }

    private static String getName(String s) {
        s = s.replaceAll("[a-zA-Z]+\\.", "");
        Matcher matcher = Pattern.compile("([a-zA-Z0-9_]+\\s*\\([\\s\\S]*\\))").matcher(s);//"([a-zA-Z]+\\s*\\([\\s\\S]*\\))"
        if(matcher.find()) {
            return matcher.group(1);
        }
        return s;
    }

    private static String getType(String s, String name) {
        Matcher matcher = Pattern.compile("([a-zA-Z\\.\\[\\]]+)\\s+" + name).matcher(s);
        if(matcher.find()) {
            return matcher.group(1);
        }
        return s;
    }
}